package com.sky.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.DistanceAwayException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.properties.BaiDuDiTuProperties;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.utils.BaiDuMapUtil;
import com.sky.utils.HttpClientUtil;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private BaiDuDiTuProperties baiDuDiTuProperties;
    @Autowired
    private BaiDuMapUtil baiDuMapUtil;
    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 下单
     * @param ordersSubmitDTO
     * @return
     */

    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {

        //处理各种业务异常(地址簿为空,购物车为空)
        AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
        if (addressBook==null){
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        Long currentId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(currentId);

        //查询当前用户的购物车数据
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.list(shoppingCart);
        if (shoppingCartList==null||shoppingCartList.size()==0){
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }


        //2 向订单表插入一条订单数据,封装订单信息,向订单明细表插入n条数据并保存
        Orders orders=new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO,orders);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);

        String detailAddress = addressBook.getProvinceName() + addressBook.getCityName() +addressBook.getDistrictName()+ addressBook.getDetail();
        orders.setAddress(detailAddress);

        /*获取用户的经纬度*/
        String addressUser = baiDuMapUtil.getLocation(detailAddress);
        String addressShop = baiDuMapUtil.getLocation(baiDuDiTuProperties.getShopAddress());
        log.info("addressUser{}",addressUser);
        log.info("addressShop{}",addressShop);
        //利用经纬度判断距离
        Double diatance = baiDuMapUtil.getDiatance(addressShop, addressUser);
        if (diatance>5000.0){
            throw new DistanceAwayException(MessageConstant.ADDRESS_DISTANCE_AWAY);
        }


        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));//订单号
        orders.setPhone(addressBook.getPhone());
        orders.setConsignee(addressBook.getConsignee());
        orders.setUserId(currentId);

        orderMapper.insert(orders);



        //3,遍历购物车信息,生成订单明细,并保存
        ArrayList<OrderDetail> list=new ArrayList<>();
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart,orderDetail);
            orderDetail.setOrderId(orders.getId());
            list.add(orderDetail);
        }
        orderDetailMapper.insertBatch(list);

        //4.提交订单后,清空购物车
        shoppingCartMapper.deleteByUserId(currentId);

        //封装返回结果
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
                .id(orders.getId())
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .build();
        return orderSubmitVO;
    }

    /**
     * 历史订单查询
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize());
        Page<OrderVO> page=orderMapper.page(ordersPageQueryDTO);
        for (OrderVO vo : page) {
            List<OrderDetail> detailList = vo.getOrderDetailList();
            StringBuilder builder = new StringBuilder();
            for (OrderDetail orderDetail : detailList) {
                builder.append(orderDetail.getName()).append("*").append(orderDetail.getNumber()).append(";");
            }
            vo.setOrderDishes(builder.toString());
        }
        long total = page.getTotal();
        List<OrderVO> orderVOList = page.getResult();
        PageResult pageResult = new PageResult(total, orderVOList);
        return pageResult;
    }

    /**
     * 查询订单详情
     * @param id
     * @return
     */
    @Override
    public OrderVO getOrderDetail(Long id) {
        OrderVO vo=orderMapper.getOrderDetail(id);
        return vo;
    }


    /**
     * 取消订单
     * @param id
     */
    @Override
    public void cancelOrder(Long id) {
        //根据id取消订单信息,将订单状态转换为6
        Orders orders = new Orders();
        orders.setId(id);
        orders.setCancelTime(LocalDateTime.now());
        orders.setStatus(6);
        orders.setCancelReason("用户自己取消");
        orderMapper.update(orders);

    }

    /**
     * 再来一单,要根据order表中的id将菜品列表的菜重新添加到购物车中
     * 根据id查询order表得到orderDetailList集合,然后分别添加到购物车中
     * @param id
     */
    @Transactional
    public void repetition(Long id) {
        List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(id);
        Long currentId = BaseContext.getCurrentId();
        for (OrderDetail orderDetail : orderDetails) {
            ShoppingCart shoppingCart = ShoppingCart.builder()
                    .name(orderDetail.getName())
                    .image(orderDetail.getImage())
                    .userId(currentId)
                    .dishId(orderDetail.getDishId())
                    .setmealId(orderDetail.getSetmealId())
                    .dishFlavor(orderDetail.getDishFlavor())
                    .number(orderDetail.getNumber())
                    .amount(orderDetail.getAmount())
                    .createTime(LocalDateTime.now()).build();
            shoppingCartMapper.insert(shoppingCart);
        }
    }

    /**
     * 各个状态的订单数量统计
     * @return
     */
    @Override
    public OrderStatisticsVO getStatusCount() {
        Integer statusCount2 = orderMapper.getStatusCount(Orders.TO_BE_CONFIRMED);
        Integer statusCount3 = orderMapper.getStatusCount(Orders.CONFIRMED);
        Integer statusCount4 = orderMapper.getStatusCount(Orders.DELIVERY_IN_PROGRESS);

        return new OrderStatisticsVO(statusCount2,statusCount3,statusCount4);
    }

    /**
     * 接单,派送,完成订单
     * @param ordersDTO
     */
    @Override
    public void updateStatus(OrdersDTO ordersDTO) {
        Long ordersDTOId = ordersDTO.getId();
        Integer status=orderMapper.getStatusById(ordersDTOId);
        if (status>=2 && status<=3) {
            Orders orders = Orders.builder().id(ordersDTOId).status(status + 1).build();
            orderMapper.update(orders);
        }else if (status==4){
            Orders orders = Orders.builder().id(ordersDTOId).status(status + 1).deliveryTime(LocalDateTime.now()).build();
            orderMapper.update(orders);
        }
    }

    @Override
    public void cancel(OrdersCancelDTO ordersCancelDTO) {
        Orders orders = new Orders();
        orders.setStatus(6);
        orders.setId(ordersCancelDTO.getId());
        orders.setCancelReason(ordersCancelDTO.getCancelReason());
        orderMapper.update(orders);
    }

    /**
     * 用户催单
     *
     * @param id
     */
    public void reminder(Long id) {
        // 查询订单是否存在
        Orders orders = orderMapper.getById(id);
        if (orders == null) {
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        //基于WebSocket实现催单
        Map map = new HashMap();
        map.put("type", 2);//2代表用户催单
        map.put("orderId", id);
        map.put("content", "订单号：" + orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }

}
